package com.cryptoneedle.garden.service.garden.source;


import com.cryptoneedle.garden.constant.SourceConstant;
import com.cryptoneedle.garden.entity.source.metadata.SourceCatalog;
import com.cryptoneedle.garden.service.properties.SshProperties;
import com.cryptoneedle.garden.service.util.JdbcUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Date;

/**
 * <p>description: 源数据源-测试服务 </p>
 *
 * @author CryptoNeedle
 * @date 2025-06-23
 */
@Slf4j
@Service
public class ConnectionService {

    @Lazy
    @Resource
    private ConnectionService connection;

    @Autowired
    private ScriptService scriptService;

    @Resource
    private SshProperties sshProperties;
    @Resource
    private SshManager sshManager;
    @Resource
    private JdbcTemplate dorisJdbcTemplate;

    @Transactional
    public void testCatalog(SourceCatalog catalog) {
        String catalogName = catalog.getCatalogName();

        boolean serverConnected = connection.testServer(catalog);
        log.info("[TEST] {} -> 连接服务器 => {}", catalogName, serverConnected);

        boolean jdbcConnected = connection.testJdbc(catalog);
        log.info("[TEST] {} -> 连接JDBC  => {}", catalogName, jdbcConnected);

        boolean dorisConnected = connection.testDoris(catalog);
        log.info("[TEST] {} -> 连接Doris => {}", catalogName, dorisConnected);
    }

    @Transactional
    public boolean testServer(SourceCatalog catalog) {
        boolean serverConnected = false;

        // 测试
        if (SshManager.getSuccessForwardMap().containsKey(catalog.inetAddress())) {
            serverConnected = true;
        } else {
            String host = catalog.getHost();
            Integer port = catalog.getPort();

            if (sshProperties.getEnabled()) {
                try {
                    // 重新代理
                    serverConnected = sshManager.forward(host, port);
                } catch (Exception e) {
                    log.error("[TEST] 连接服务器 -> 异常 => {}", e.getMessage());
                }
            } else {
                try (Socket socket = new Socket()) {
                    socket.connect(new InetSocketAddress(host, port), sshProperties.getTimeout());
                    serverConnected = true;
                } catch (IOException e) {
                    log.error("[TEST] 连接服务器 -> 异常 => {}", e.getMessage());
                }
            }
        }

        // 保存 SourceServer 链接信息
        catalog.setServerConnected(serverConnected);
        if (serverConnected) {
            catalog.setServerConnectedDt(new Date());
        }

        return serverConnected;
    }

    @Transactional
    public boolean testJdbc(SourceCatalog catalog) {
        String version = null;

        // 测试
        try {
            JdbcTemplate jdbcTemplate = JdbcUtil.getJdbcTemplate(catalog);
            version = jdbcTemplate.queryForObject(catalog.getDatabaseType()
                    .getDatabase()
                    .getDatabaseVersionSql(), String.class);
        } catch (Exception e) {
            log.error("[TEST] 连接JDBC -> 异常 => {}", e.getMessage());
        }

        // 保存 JDBC 链接信息
        boolean jdbcConnected = StringUtils.isNotEmpty(version);
        catalog.setJdbcConnected(jdbcConnected);
        if (jdbcConnected) {
            catalog.setDatabaseVersion(version);
            catalog.setJdbcConnectedDt(new Date());
        }
        return jdbcConnected;
    }

    @Transactional
    public boolean testDoris(SourceCatalog catalog) {
        boolean dorisConnected = false;

        // 测试
        String dorisCatalogName = catalog.getDorisCatalogName();
        if (!StringUtils.isBlank(dorisCatalogName)) {
            try {
                String dropTestCatalogSql = String.format("DROP CATALOG IF EXISTS %s%s", SourceConstant.TEST_CATALOG_PREFIX, dorisCatalogName);
                dorisJdbcTemplate.execute(dropTestCatalogSql);

                String createTestCatalogSql = scriptService.createCatalog(catalog, true);
                dorisJdbcTemplate.execute(createTestCatalogSql);

                dropTestCatalogSql = String.format("DROP CATALOG %s%s", SourceConstant.TEST_CATALOG_PREFIX, dorisCatalogName);
                dorisJdbcTemplate.execute(dropTestCatalogSql);

                dorisConnected = true;
            } catch (Exception e) {
                log.error("[TEST] 连接Doris -> 异常 => {}", e.getMessage());
            }
        }


        // 保存 SourceCatalog 链接信息
        catalog.setDorisConnected(dorisConnected);
        if (dorisConnected) {
            catalog.setDorisConnectedDt(new Date());
        }
        return dorisConnected;
    }
}